<?php
	require_once('config.php');

	function error_handler($errno, $errstr) {
		printf('{"result":"error","error":"The request failed. Please try again.\n\nIf the error persists, please report the following error:\n%s"}', $errstr);
		exit;
	}

	set_error_handler('error_handler');
	error_reporting(E_ALL | E_STRICT);

	require_once('JSON.php');

	class InOut {
		public $value;

		function __construct($value = null) {
			$this->value = $value;
		}
	}

	function sql_value($value) {
		switch (true) {
			case is_numeric($value):
			default:
				return $value;
			case is_string($value):
				return '\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), $value) . '\'';
			case is_null($value):
				return 'NULL';
			case $value instanceof InOut:
				return sql_value($value->value);
		}
	}

	function call_proc($proc, $args = array()) {
		$query = '';
		$params = array();

		$arg_list = '';
		foreach ($args as $key => $arg) {
			$value = sql_value($arg);

			if ($arg instanceof InOut) {
				$param = '@p' . $key;
				$params[$param] = $arg;
				$query .= sprintf('SET %s = %s;', $param, $value);
				$value = $param;
			}

			$arg_list .= ($arg_list ? ',' : '') . $value;
		}

		$query .= sprintf('CALL %s(%s);', $proc, $arg_list);

		if (count($params)) $query .= 'SELECT ' . implode(',', array_keys($params)) . ';';

		$mysql = new mysqli(TACK_MYSQL_HOST, TACK_MYSQL_USER, TACK_MYSQL_PASS, TACK_MYSQL_DB);
		if ($mysql->multi_query($query)) {
			$results = array();

			do {
				if ($result = $mysql->store_result()) {
					if ($mysql->more_results() || empty($params)) {
						$data = array();
						while ($row = $result->fetch_assoc()) $data[] = $row;
						$results[] = $data;
					} else if ($row = $result->fetch_assoc()) {
						foreach ($row as $column => $value) {
							if (isset($params[$column])) $params[$column]->value = $value;
						}
					}

					$result->close();
				}
			} while ($mysql->next_result());

			return $results;
		} else {
			return false;
		}
	}

	function form_value($key) {
		if (empty($_REQUEST[$key])) return '';
		return get_magic_quotes_gpc() ? stripslashes($_REQUEST[$key]) : $_REQUEST[$key];
	}

	switch ($_REQUEST['action']) {
		case 'get':
			$gameId = (int)$_REQUEST['gameId'];
			$results = call_proc('tack_get', array($gameId));

			if (empty($results[0]))
				print '{"result":"error","error":"The requested game could not be loaded."}';
			else
				printf('{"result":"success","gameId":%d,"thumbsUp":%d,"thumbsDown":%d,"game":%s}', $gameId, $results[0][0]['thumbs_up'], $results[0][0]['thumbs_down'], $results[0][0]['data']);

			exit;
		case 'set':
			$authKey = new InOut(empty($_REQUEST['authKey']) ? null : form_value('authKey'));

			$json = new Services_JSON();

			if (!$game = $json->decode(form_value('data'))) {
				print '{"result":"error","error":"Invalid game data."}';
				exit;
			}
			
			$data = $json->encode($game);

			$gameId = new InOut();
			call_proc('tack_set', array($gameId, $authKey, $game->title, $game->author, $game->description, $data));

			if ($authKey->value)
				printf('{"result":"success","authKey":"%s","gameId":%d}', $authKey->value, $gameId->value);
			else
				print '{"result":"error","error":"Invalid authorization key."}';

			exit;
	}

?>